package org.mapsforge.android.maps;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.support.v4.app.Fragment;

public class MapFragment extends Fragment {
	
	/**
	 * Name of the file where the map position and other settings are stored.
	 */
	private static final String PREFERENCES_FILE = "MapActivity";

	/**
	 * Counter to store the last ID given to a MapView.
	 */
	private int lastMapViewId;

	/**
	 * Internal list which contains references to all running MapView objects.
	 */
	private ArrayList<MapView> mapViews = new ArrayList<MapView>(2);

	private void destroyMapViews() {
		if (this.mapViews != null) {
			MapView currentMapView;
			while (!this.mapViews.isEmpty()) {
				currentMapView = this.mapViews.get(0);
				currentMapView.destroy();
			}
			currentMapView = null;
			this.mapViews.clear();
			this.mapViews = null;
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		destroyMapViews();
	}

	@Override
	public void onPause() {
		super.onPause();
		Editor editor = getActivity().getSharedPreferences(PREFERENCES_FILE, Activity.MODE_PRIVATE).edit();
		for (MapView currentMapView : this.mapViews) {
			currentMapView.onPause();

			editor.clear();
			if (currentMapView.hasValidCenter()) {
				if (!currentMapView.getMapViewMode().requiresInternetConnection()
						&& currentMapView.hasValidMapFile()) {
					// save the map file
					editor.putString("mapFile", currentMapView.getMapFile());
				}
				// save the map position and zoom level
				GeoPoint mapCenter = currentMapView.getMapCenter();
				editor.putInt("latitude", mapCenter.getLatitudeE6());
				editor.putInt("longitude", mapCenter.getLongitudeE6());
				editor.putInt("zoomLevel", currentMapView.getZoomLevel());
			}
			editor.commit();
		}

		if (isRemoving()) {
			destroyMapViews();
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		for (MapView currentMapView : this.mapViews) {
			currentMapView.onResume();
		}
	}
	
	public MapFragmentContext getMapContext()
	{
		return new MapFragmentContext(getActivity().getApplicationContext());		
	}

	
	private class MapFragmentContext extends ContextWrapper implements MapContext
	{
		public MapFragmentContext(Context base) {
			super(base);
		}

		/**
		 * Returns a unique MapView ID on each call.
		 * 
		 * @return the new MapView ID.
		 */
		public int getMapViewId() {
			return ++MapFragment.this.lastMapViewId;
		}

		/**
		 * This method is called once by each MapView during its setup process.
		 * 
		 * @param mapView
		 *            the calling MapView.
		 */
		@Override
		public void registerMapView(MapView mapView) {
			if (MapFragment.this.mapViews != null) {
				MapFragment.this.mapViews.add(mapView);

				SharedPreferences preferences = getActivity().getSharedPreferences(PREFERENCES_FILE, Activity.MODE_PRIVATE);
				// restore the position
				if (preferences.contains("latitude") && preferences.contains("longitude")
						&& preferences.contains("zoomLevel")) {
					if (!mapView.getMapViewMode().requiresInternetConnection()
							&& preferences.contains("mapFile")) {
						// get and set the map file
						mapView.setMapFileFromPreferences(preferences.getString("mapFile", null));
					}

					// get and set the map position and zoom level
					GeoPoint defaultStartPoint = mapView.getDefaultStartPoint();
					mapView.setCenterAndZoom(new GeoPoint(preferences.getInt("latitude",
							defaultStartPoint.getLatitudeE6()), preferences.getInt("longitude",
							defaultStartPoint.getLongitudeE6())), (byte) preferences.getInt(
							"zoomLevel", mapView.getDefaultZoomLevel()));
				}
			}
		}

		/**
		 * This method is called once by each MapView when it gets destroyed.
		 * 
		 * @param mapView
		 *            the calling MapView.
		 */
		@Override
		public void unregisterMapView(MapView mapView) {
			if (MapFragment.this.mapViews != null) {
				MapFragment.this.mapViews.remove(mapView);
			}
		}

		
	}

}
